package org.anyline.simiple;


import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.util.*;

public class PDFTableParser {
    private static final float CELL_MERGE_THRESHOLD = 1.5f;

    static class TableCell {
        Rectangle2D bounds;
        String content = "";
        int rowSpan = 1;
        int colSpan = 1;
        boolean processed = false;

        TableCell(Rectangle2D bounds) {
            this.bounds = bounds;
        }

        void appendText(String text) {
            this.content += (this.content.isEmpty() ? "" : " ") + text;
        }
    }

    public static String parseToHTML(File pdfFile) throws IOException {
        try (PDDocument doc = PDDocument.load(pdfFile)) {
            List<TableCell> cells = new ArrayList<>();
            PDFTextStripper stripper = new PDFTextStripper() {
                @Override
                protected void writeString(String text, List<TextPosition> textPositions) {
                    if (textPositions.isEmpty()) return;

                    TextPosition first = textPositions.get(0);
                    Rectangle2D cellRect = new Rectangle2D.Float(
                            first.getXDirAdj(), first.getYDirAdj(),
                            textPositions.get(textPositions.size()-1).getWidthDirAdj(),
                            first.getHeight()
                    );

                    Optional<TableCell> existing = cells.stream()
                            .filter(c -> c.bounds.intersects(cellRect))
                            .findFirst();

                    if (existing.isPresent()) {
                        existing.get().appendText(text);
                    } else {
                        TableCell cell = new TableCell(cellRect);
                        cell.appendText(text);
                        cells.add(cell);
                    }
                }
            };
            stripper.setSortByPosition(true);
            stripper.getText(doc);

            // 动态检测合并单元格
            detectMergedCells(cells);
            return generateHTML(cells);
        }
    }

    private static void detectMergedCells(List<TableCell> cells) {
        cells.sort(Comparator.comparingDouble(c -> c.bounds.getY()));

        for (int i = 0; i < cells.size(); i++) {
            TableCell current = cells.get(i);
            if (current.processed) continue;

            // 检测列合并
            for (int j = i + 1; j < cells.size(); j++) {
                TableCell next = cells.get(j);
                if (Math.abs(next.bounds.getY() - current.bounds.getY()) < 2
                        && next.content.equals(current.content)) {
                    current.colSpan++;
                    next.processed = true;
                }
            }

            // 检测行合并
            for (int j = i + 1; j < cells.size(); j++) {
                TableCell next = cells.get(j);
                if (Math.abs(next.bounds.getX() - current.bounds.getX()) < 2
                        && next.content.equals(current.content)) {
                    current.rowSpan++;
                    next.processed = true;
                }
            }
        }
    }

    private static String generateHTML(List<TableCell> cells) {
        StringBuilder html = new StringBuilder("<table border='1'>");
        cells.stream()
                .filter(c -> !c.processed)
                .sorted(Comparator.comparingDouble(c -> c.bounds.getY()))
                .forEach(c -> {
                    html.append("<td");
                    if (c.rowSpan > 1) html.append(" rowspan='").append(c.rowSpan).append("'");
                    if (c.colSpan > 1) html.append(" colspan='").append(c.colSpan).append("'");
                    html.append(">").append(c.content).append("</td>");
                });
        return html.append("</table>").toString();
    }

    public static void main(String[] args) throws IOException {
        System.out.println(parseToHTML(new File("d:\\order.pdf")));
    }
}
